package com.weituotian.controller;

import com.alibaba.fastjson.JSONObject;
import com.weituotian.common.controller.BaseController;
import com.weituotian.common.exception.ControllerException;
import com.weituotian.common.exception.ServiceException;
import com.weituotian.common.result.Menu;
import com.weituotian.common.result.Node;
import com.weituotian.common.result.Result;
import com.weituotian.common.result.TableResult;
import com.weituotian.common.utils.PageInfo;
import com.weituotian.model.Resource;
import com.weituotian.model.ResourceType;
import com.weituotian.model.User;
import com.weituotian.model.enums.ResourceStateEnum;
import com.weituotian.model.vo.ResourceVo;
import com.weituotian.service.IResourceService;
import com.weituotian.service.IResourceTypeService;
import com.weituotian.service.IRoleService;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 资源控制器
 * 本控制器处理doedit的方式和其它控制器不一样
 * 不是返回ajax,而是用重定向的方式提示信息和要求重新修改
 * <p>
 * Created by Administrator on 2016-09-26.
 */
@Controller("resourceController")
@RequestMapping("/resource")
public class ResourceController extends BaseController {


    private final IRoleService roleService;

    @Autowired
    private IResourceService resourceService;

    @Autowired
    private IResourceTypeService resourceTypeService;


    @Autowired
    public ResourceController(IRoleService roleService) {
        this.roleService = roleService;
    }


    @RequestMapping(value = "/ajaxlist", produces = "application/json; charset=utf-8")
    @ResponseBody
    public Result ajaxList(String search_name, String search_parent, String search_res_type, Integer offset, Integer limit,
                           String sort, String order) {
        //返回的json
        Result result = new Result();

        PageInfo<ResourceVo> pageInfo = new PageInfo<ResourceVo>(1, limit);

        //这里的offset会覆盖pageinfo构造函数中根据当前页数page计算的offset
        offset = offset == null ? 0 : offset;
        pageInfo.setFrom(offset);

        //排序
        if (StringUtils.isNotBlank(sort) && StringUtils.isNotBlank(order)) {
            pageInfo.addSort(sort, order);
        }

        //搜索条件
        Map<String, Object> condition = new HashMap<String, Object>();
        if (search_name != null) {//资源名称
            if (StringUtils.isNoneBlank(search_name)) {
                condition.put("search_name", search_name);
            }
        }
        if (search_res_type != null) {//资源类型
            if (StringUtils.isNoneBlank(search_res_type)) {
                condition.put("search_res_type", search_res_type);
            }
        }
        if (search_parent != null) {//父资源
            if (StringUtils.isNoneBlank(search_parent)) {
                condition.put("search_parent", search_parent);
            }
        }
        pageInfo.setCondition(condition);
        resourceService.getListVo(pageInfo);

        TableResult tableResult = new TableResult(pageInfo.getTotal(), pageInfo.getList());

        result.setSuccess(true);
        result.setObj(tableResult);
        result.setMsg("获取成功");

        return result;

//        model.addAttribute("pageinfo", pageInfo);
//        return "resource/index";
    }

    @RequestMapping(value = "/ajaxtree", produces = "application/json; charset=utf-8")
    @ResponseBody
    public Result ajaxPage(String pid) {
        List<ResourceVo> all = resourceService.getResourceJsTree(pid);
        Result result = new Result();
        if (pid.equals("#")) {
            //创建根节点
            ResourceVo resourceVo = new ResourceVo();

            resourceVo.setChildren(all);
            resourceVo.setIcon("fa fa-book");
            resourceVo.setText("根目录");
            resourceVo.setId(0);
            //节点状态
            ResourceVo.State state = resourceVo.new State();
            state.opened = true;
            resourceVo.setState(state);

            result.setObj(resourceVo);
        } else {
            //否则返回列表
            result.setObj(all);
        }
        result.setSuccess(true);
        result.setMsg("获取资源列表成功");
        return result;
    }

    @RequestMapping(value = "/selecttree")
    public String selectTree(Model model) {
        List<Resource> res = resourceService.getAllResourceList();
        model.addAttribute("list", JSONObject.toJSONString(res));
        return "resource/select";
    }

    @RequestMapping(value = "/index")
    public String index(Model model) {

        //资源类型
        List<ResourceType> resTypes = resourceTypeService.getAllResourceTypeList();


        model.addAttribute("resTypes", resTypes);
        model.addAttribute("edit_url", this.getContextPath() + "/resource/edit");
        model.addAttribute("add_url", this.getContextPath() + "/resource/add");
        model.addAttribute("delete_url", this.getContextPath() + "/resource/delete");
        model.addAttribute("pageName", "资源列表");
        return "resource/index";
    }

    /**
     * 列表[废弃]
     *
     * @param page 当前页数
     * @return
     */
    @RequestMapping(value = "/list")
    public String list(String search_name, String search_res_type, Integer page, Model model) {
        PageInfo<Resource> pageInfo = new PageInfo<Resource>(page, 9999);

        //搜索条件
        Map<String, Object> condition = new HashMap<String, Object>();
        if (search_name != null) {//资源名称
            if (StringUtils.isNoneBlank(search_name)) {
                condition.put("search_name", search_name);
            }
        }
        if (search_res_type != null) {//资源类型
            if (StringUtils.isNoneBlank(search_res_type)) {
                condition.put("search_res_type", search_res_type);
            }
        }
        pageInfo.setCondition(condition);
        resourceService.getList(pageInfo);

        //资源类型
        List<ResourceType> resTypes = resourceTypeService.getAllResourceTypeList();

        //树形列表
        List<Resource> all = pageInfo.getList();// resourceService.getAllResourceList();
        List<Node<Resource>> tree = resourceService.findALLTree(all);

        model.addAttribute("resourceTree", tree);
        model.addAttribute("pageinfo", pageInfo);
        model.addAttribute("resTypes", resTypes);
        return "resource/tables";
    }

    /**
     * 增加页面
     *
     * @param model
     * @return
     */
    @RequestMapping("/add")
    public String add(Integer pid, Model model, @ModelAttribute("resource") Resource redirectResource, @ModelAttribute("msg") String msg) {
        Resource resource;

        if (redirectResource != null && redirectResource.getName() != null) {//重定向时候的处理
            resource = redirectResource;

            pid = redirectResource.getPid();
            model.addAttribute("msg", msg);
        } else {
            //资源
            resource = new Resource();
            resource.setStatus(ResourceStateEnum.OPEN);//默认为1
            resource.setCreateTime(new Date());
            resource.setUrl("/");
            resource.setSeq(1);

        }

        Resource pResource;
        //pid检测
        if (pid == null || pid <= 0) {
            pid = 0;//默认为0
            pResource = new Resource();
            pResource.setPid(pid);
            pResource.setName("根目录");
        } else {
            //父资源处理
            pResource = resourceService.findById(pid);
            if (pResource == null) {
                pid = 0;
                pResource = new Resource();
                pResource.setPid(pid);
                pResource.setName("根目录");
            }
        }

        resource.setPid(pid);

        //所有资源列表,用于选择父资源,已经用ajax取代
        /*List<Resource> resources = resourceService.getAllResourceList();
        List<Node<Resource>> allTree = resourceService.findALLTree(resources);*/

        //资源类型列表
        List<ResourceType> restypes = resourceTypeService.getAllResourceTypeList();


        model.addAttribute("resource", resource);
        model.addAttribute("pResource", pResource);
//        model.addAttribute("allTree", allTree);
        model.addAttribute("resTypes", restypes);
        model.addAttribute("resStatus", ResourceStateEnum.values());//资源状态
        model.addAttribute("form_url", this.getContextPath() + "/resource/doadd");//表单地址
        model.addAttribute("action", "add");
        model.addAttribute("pageName", "资源添加");
        return "resource/edit";
    }

    /**
     * 处理增加用户
     *
     * @param resource
     * @return
     */
    @RequestMapping(value = "/doadd")
    public Object doadd(Resource resource, RedirectAttributes attributes) {
        resource.setCreateTime(new Date());
        resource.setSeq(1);
        try {
            resourceService.add(resource);
        } catch (Exception e) {
            e.printStackTrace();
//            return renderError(e.getMessage());
            attributes.addFlashAttribute("resource", resource);
            attributes.addFlashAttribute("msg", "数据库写入时发生了错误");
            logger.debug("resource doadd exception:{}", StringEscapeUtils.escapeHtml4(e.getMessage()));
            return "redirect:/resource/add";
        }

        attributes.addFlashAttribute("msg", "增加成功");
        return showMessage();

//        return renderSuccess("增加成功!");
    }

    /**
     * 编辑页面
     *
     * @return
     */
    @RequestMapping(value = "/edit")
    public String edit(Integer id, Model model, @ModelAttribute("resource") Resource redirectResource, @ModelAttribute("msg") String msg) throws ControllerException {
        Resource resource;

        if (redirectResource != null && redirectResource.getPid() != null) {
            //重定向,id不为null，redirectResource肯定也不为null，id注入的同时，redirectResource也被初始化
            resource = redirectResource;
            model.addAttribute("msg", msg);
        } else {
            if (id == null || id < 0) {
                throw new ControllerException("资源id不合法");//交给spring分发到错误页面
            }
            //资源
            resource = resourceService.findById(id);
            if (resource == null) {
                throw new ControllerException("没有找到这个资源");//交给spring分发到错误页面
            }
        }


        //父资源
        Resource pResource = resourceService.findById(resource.getPid());

        //所有资源列表,已经用ajax取代
        /*List<Resource> resources = resourceService.getAllResourceList();
        List<Node<Resource>> allTree = resourceService.findALLTree(resources);*/

        //资源类型列表
        List<ResourceType> restypes = resourceTypeService.getAllResourceTypeList();

        model.addAttribute("resource", resource);
        model.addAttribute("pResource", pResource);
        model.addAttribute("resTypes", restypes);
//        model.addAttribute("allTree", allTree);
        model.addAttribute("resStatus", ResourceStateEnum.values());//资源状态
        model.addAttribute("form_url", this.getContextPath() + "/resource/doedit");//表单地址
        model.addAttribute("action", "edit");
        model.addAttribute("pageName", "资源编辑");
        return "resource/edit";
    }

    /**
     * 处理编辑
     *
     * @return
     */
    @RequestMapping(value = "/doedit")
//    @ResponseBody
    public Object doedit(Resource resource, RedirectAttributes attributes) {
        try {
            resourceService.update(resource);
        } catch (ServiceException e) {
            e.printStackTrace();
            attributes.addFlashAttribute("resource", resource);
            attributes.addFlashAttribute("msg", e.getMessage());
            return "redirect:/resource/edit";
//            return renderError("修改失败！");
        }
        attributes.addFlashAttribute("msg", "修改成功");
        return showMessage();
//        return renderSuccess("修改成功！");
    }

    /**
     * 批量删除
     * @param ids id
     * @return
     */
    @RequestMapping(value = "/delete", produces = "application/json; charset=utf-8")
    @ResponseBody
    public Object delete(@RequestParam(value = "ids[]") Integer[] ids) {
        try {
            resourceService.deleteByIds(ids);
        } catch (Exception e) {
            e.printStackTrace();
            return renderError("删除失败!");
        }
        return renderSuccess("删除成功!");
    }

    /**
     * 选择图标
     *
     * @return
     */
    @RequestMapping("/selecticon")
    public String selectIcon(Model model) {
        model.addAttribute("pageName", "资源编辑");
        return "resource/selecticon";
    }

    /**
     * 一键创建增删查改资源
     *
     * @return
     */
    @RequestMapping(value = "/autocreate")
    public Object autoCreate(String controller_name, String descript) throws ControllerException {
        try {
            resourceService.autoCreateCRUD(controller_name, descript);
        } catch (ServiceException e) {
            e.printStackTrace();
            throw new ControllerException(e.getMessage());//交给spring分发到错误页面
            //return renderError(e.getMessage());
        }
        return "redirect:list";
        //return renderSuccess("一键创建成功!");
    }

    /**
     * ajax获取菜单
     *
     * @return
     */
    @RequestMapping(value = "/getmenu", produces = "application/json; charset=utf-8")
    @ResponseBody
    public Object menu() {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        Result result = new Result();

        if (user != null) {

            //改为js生成树,后台不再生成树
            //List<Menu> tree = getMenuTree(user);
            List<Resource> resources;
            if (user.isSuperAdmin()) {
                resources = resourceService.findMenusAll();
            } else {
                resources = resourceService.findMenusByUserId(user.getId());
            }

            resourceService.AddContextPath(resources,this.getContextPath());

            result.setSuccess(true);
            result.setObj(resources);
            result.setMsg("获取菜单成功");

        } else {
            result.setSuccess(false);
            result.setMsg("出现错误,当前用户不存在");
        }
        return result;
    }

    /**
     * 获取菜单树
     *
     * @param user 当前用户
     * @return
     */
    @Cacheable(value = "menuCache", key = "#user.id")
    public List<Menu> getMenuTree(User user) {
        List<Resource> resources;
        if (user.isSuperAdmin()) {
            resources = resourceService.findMenusAll();
        } else {
            resources = resourceService.findMenusByUserId(user.getId());
        }

        //转化为树形菜单
        List<Menu> menus = resourceService.findAllMenu(resources);

        //List<Node<Resource>> tree = resourceService.findALLTree(menus);

        return menus;
    }


}
